package com.itheima.sfbx.insurance.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.sfbx.framework.commons.constant.basic.SuperConstant;
import com.itheima.sfbx.framework.commons.constant.insure.InsureConstant;
import com.itheima.sfbx.framework.commons.dto.basic.TreeVO;
import com.itheima.sfbx.framework.commons.exception.ProjectException;
import com.itheima.sfbx.framework.commons.utils.BeanConv;
import com.itheima.sfbx.framework.commons.utils.EmptyUtil;
import com.itheima.sfbx.framework.commons.utils.NoProcessing;
import com.itheima.sfbx.insurance.dto.CategoryCoefficentVO;
import com.itheima.sfbx.insurance.dto.CategoryConditionVO;
import com.itheima.sfbx.insurance.dto.CategorySafeguardVO;
import com.itheima.sfbx.insurance.dto.CategoryVO;
import com.itheima.sfbx.insurance.enums.CategoryEnum;
import com.itheima.sfbx.insurance.mapper.CategoryMapper;
import com.itheima.sfbx.insurance.pojo.Category;
import com.itheima.sfbx.insurance.pojo.CategoryCoefficent;
import com.itheima.sfbx.insurance.pojo.CategoryCondition;
import com.itheima.sfbx.insurance.pojo.CategorySafeguard;
import com.itheima.sfbx.insurance.service.ICategoryCoefficentService;
import com.itheima.sfbx.insurance.service.ICategoryConditionService;
import com.itheima.sfbx.insurance.service.ICategorySafeguardService;
import com.itheima.sfbx.insurance.service.ICategoryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description：保险分类服务实现类
 */
@Slf4j
@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements ICategoryService {

    @Autowired
    ICategoryConditionService categoryConditionService;

    @Autowired
    ICategoryCoefficentService categoryCoefficentService;

    @Autowired
    ICategorySafeguardService categorySafeguardService;


    /**
     * 构建查询条件
     * @param categoryVO
     */
    private LambdaQueryWrapper<Category> queryWrapper(CategoryVO categoryVO) {
        LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StrUtil.isNotBlank(categoryVO.getCategoryNo()),Category::getCategoryNo, categoryVO.getCategoryNo());
        queryWrapper.eq(StrUtil.isNotBlank(categoryVO.getCategoryType()),Category::getCategoryType, categoryVO.getCategoryType());
        queryWrapper.eq(StrUtil.isNotBlank(categoryVO.getCategoryName()),Category::getCategoryName,categoryVO.getCategoryName());
        queryWrapper.eq(StrUtil.isNotBlank(categoryVO.getParentCategoryNo()),Category::getParentCategoryNo,categoryVO.getParentCategoryNo());
        queryWrapper.eq(StrUtil.isNotBlank(categoryVO.getDataState()),Category::getDataState,categoryVO.getDataState());
        queryWrapper.eq(StrUtil.isNotBlank(categoryVO.getLeafNode()),Category::getLeafNode,categoryVO.getLeafNode());
        queryWrapper.eq(StrUtil.isNotBlank(categoryVO.getShowIndex()),Category::getShowIndex,categoryVO.getShowIndex());
        return queryWrapper;
    }



    /**
     * 构建返回对象
     * @param voList
     */
    private void buildVoList(List<CategoryVO> voList) {
        //将被分类编号遍历出来
        Set<String> noSet = voList.stream()
                .map(CategoryVO::getCategoryNo)
                .collect(Collectors.toSet());
        //构建分类筛选项
        List<CategoryCondition> conditionList =
                categoryConditionService
                        .lambdaQuery()
                        .in(CategoryCondition::getCategoryNo, noSet)
                        .list();
        Map<String, List<CategoryCondition>> conditionMap = conditionList
                .stream()
                .collect(Collectors
                        .groupingBy(CategoryCondition::getCategoryNo));
        //构建分类系数项
        List<CategoryCoefficent> coefficentList = categoryCoefficentService
                .lambdaQuery()
                .in(CategoryCoefficent::getCategoryNo, noSet)
                .list();
        Map<String, List<CategoryCoefficent>> coefficentMap = coefficentList
                .stream()
                .collect(Collectors.groupingBy(CategoryCoefficent::getCategoryNo));
        //构建分类保障项
        List<CategorySafeguard> safeguardList = categorySafeguardService
                .lambdaQuery()
                .in(CategorySafeguard::getCategoryNo, noSet)
                .list();
        Map<String, List<CategorySafeguard>> safeguardMap = safeguardList
                .stream()
                .collect(Collectors
                        .groupingBy(CategorySafeguard::getCategoryNo));
        //封装返回对象
        for (CategoryVO vo : voList) {
            List<CategoryCondition> conditions = conditionMap.get(vo.getCategoryNo());
            vo.setCategoryConditionVOs(BeanConv.toBeanList(conditions, CategoryConditionVO.class));
            List<CategoryCoefficent> coefficents = coefficentMap.get(vo.getCategoryNo());
            vo.setCategoryCoefficentVOs(BeanConv.toBeanList(coefficents, CategoryCoefficentVO.class));
            List<CategorySafeguard> safeguards = safeguardMap.get(vo.getCategoryNo());
            vo.setCategorySafeguardVOs(BeanConv.toBeanList(safeguards, CategorySafeguardVO.class));
        }
    }


    /**
     * 分类分页列表查询
     * @param categoryVO 保险分类查询条件
     * @param pageNum 页码
     * @param pageSize 每页条数
     * @return
     */
    @Override
    public Page<CategoryVO> findPage(CategoryVO categoryVO, int pageNum, int pageSize) {
        //构建查询条件
        Page<Category> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<Category> query = queryWrapper(categoryVO);
        Page<Category> vo = this.page(page, query);
        Page<CategoryVO> voPage = BeanConv.toPage(vo, CategoryVO.class);
        List<CategoryVO> voList = voPage.getRecords();
        if (CollUtil.isEmpty(voList)) {
            return voPage;
        }
        //构建返回对象
        buildVoList(voList);
        return voPage;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public CategoryVO save(CategoryVO categoryVO) {
        //TODO
        return null;
    }

    /**
     * 保存分类关系列表
     * @param categoryVO 保险分类对象
     * @return
     */
    @Override
    @Transactional
    public Boolean update(CategoryVO categoryVO) {
        //先将分类关系列表全部删除掉，再新增
        //查询分类是否存在
        Category category = getById(categoryVO.getId());
        if (category == null){
            throw new ProjectException(CategoryEnum.UPDATE_FAIL);
        }
        //存在就直接修改
        updateById(BeanConv.toBean(categoryVO, Category.class));
        //将分类列表，分类筛选项，分类系数项，分类保障项全部删除
        categoryConditionService.deleteByCategoryNo(categoryVO.getCategoryNo());
        categoryCoefficentService.deleteByCategoryNo(categoryVO.getCategoryNo());
        categorySafeguardService.deleteByCategoryNo(categoryVO.getCategoryNo());
        //将所有数据取出来
        List<CategoryConditionVO> conditionVos = categoryVO.getCategoryConditionVOs();
        List<CategoryCoefficentVO> coefficentVos = categoryVO.getCategoryCoefficentVOs();
        List<CategorySafeguardVO> safeguardVos = categoryVO.getCategorySafeguardVOs();
        List<CategoryCondition> conditions = null;
        List<CategoryCoefficent> coefficents = null;
        List<CategorySafeguard> safeguards = null;
        //将删除掉的数据新增
        if (CollUtil.isNotEmpty(conditionVos)){
            //将数据遍历成需要的对象
            conditions = conditionVos.stream().map(v -> {
                v.setCategoryNo(category.getCategoryNo());
                return BeanConv.toBean(v, CategoryCondition.class);
            }).collect(Collectors.toList());
        }
        categoryConditionService.saveBatch(conditions);
        if (CollUtil.isNotEmpty(coefficentVos)){
            coefficents = coefficentVos.stream().map(v -> {
                v.setCategoryNo(category.getCategoryNo());
                return BeanConv.toBean(v, CategoryCoefficent.class);
            }).collect(Collectors.toList());
        }
        categoryCoefficentService.saveBatch(coefficents);
        if (CollUtil.isNotEmpty(safeguardVos)){
            safeguards = safeguardVos.stream().map(v -> {
                v.setCategoryNo(category.getCategoryNo());
                return BeanConv.toBean(v, CategorySafeguard.class);
            }).collect(Collectors.toList());
        }
        categorySafeguardService.saveBatch(safeguards);
        return null;
    }

    @Override
    @Transactional
    public Boolean delete(String[] checkedIds) {
        //TODO
        return null;
    }

    @Override
    public List<CategoryVO> findList(CategoryVO categoryVO) {
        //TODO
        return null;
    }



    @Override
    public TreeVO categoryTreeVO(String parentCategoryNo, String categoryType,String[] checkedCategoryNos) {
        //TODO
        return null;
    }

    @Override
    public String createCategoryNo(String parentCategoryNo) {
        CategoryVO categoryVO = CategoryVO.builder()
            .parentCategoryNo(parentCategoryNo)
            .build();
        QueryWrapper<Category> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Category::getParentCategoryNo,parentCategoryNo);
        List<Category> categoryList = list(queryWrapper);
        //无下属节点则创建下属节点
        if (EmptyUtil.isNullOrEmpty(categoryList)){
            return NoProcessing.createNo(parentCategoryNo,false);
        //有下属节点则累加下属节点
        }else {
            Long categoryNo = categoryList.stream()
                .map(category -> { return Long.valueOf(category.getCategoryNo());})
                .max(Comparator.comparing(i -> i)).get();
            return NoProcessing.createNo(String.valueOf(categoryNo),true);
        }
    }

    /**
     * 人种榜险种榜分类
      * @param type
     */
    @Override
    public List<CategoryVO> categoryCheckRule(String type) {
        //判断是否是险种榜
        if(InsureConstant.checkIsInsureType(type)){
            List<CategoryVO> res = new ArrayList<>();
            //获取所有的险种榜
            List<String> allCheckRule = InsureConstant.getAllCheckRule();
            allCheckRule.forEach(e->{
                CategoryVO categoryVO = CategoryVO.builder().categoryNo(e).categoryName(InsureConstant.getRuleNameById(e)).build();
                res.add(categoryVO);
            });
            return res;
        }else{
            //说明是人种榜
            List<String> categoryNames = Arrays.asList("成年人", "少儿", "老人");
            LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.in(Category::getCategoryName,categoryNames);
            queryWrapper.eq(Category::getDataState,SuperConstant.DATA_STATE_0);
            List<CategoryVO> res = BeanConv.toBeanList(list(queryWrapper), CategoryVO.class);
            return res;
        }
    }
}
